#!/usr/bin/env bash
# 此文件用于保存配置。勿动
#base_path="$HOME/code/java/ops/GSC-P3内容"
base_path=$(pwd)
clone_config_file="$base_path/ops.properties"
ops_base_path="${base_path%%/Documents/*}/Documents/ops"

ops_global_path="${base_path%%/Documents/*}/Documents/ops/ops_global.properties"
ops_user=$(of "read_config" "ops_user" "" "$ops_global_path")
spinner="/|\\-"
# 创建日志文件路径
log_file="$ops_base_path/log/$(date +'%Y-%m-%d')-ob.log"  # 你可以修改为其他日志路径
if [ ! -d "$ops_base_path/log" ]; then
  mkdir -p "$ops_base_path/log"
fi
if [ ! -f "$log_file" ]; then
  touch "$log_file"
fi
# 日志函数
# 日志函数
log() {
    local message=$1
    echo "$(date +'%Y-%m-%d %H:%M:%S') - $message" | tee -a "$log_file" >&2
}

# 读取配置的函数
read_config() {
    local key=$1
    # 使用 grep 提取 key 的值，使用 `=` 分隔确保读取完整值
    value=$(grep -E "^$key=" "$clone_config_file" | sed -E "s/^$key=//")
    echo "$value"
}
# 定义帮助信息
show_help() {
  echo "当前目录:$base_path"
  ## 检查配置信息
  type=$(read_config "type")
  # 使用 IFS 分隔字符串为数组
  while IFS=',' read -r -a temp; do
    types=("${temp[@]}")
  done < <(echo "$type")
  # 遍历数组，并根据条件拼接字符串
  for t in "${types[@]}"; do
      case "$t" in
          1)
              result+="普通发布单"
              ;;
          2)
              result+="依赖发布单"
              ;;
          3)
              result+="发布计划"
              ;;
          *)
      esac
  done

   echo "用法: ob (ops-build) [选项]"
   echo ""
   echo "选项:"
   echo "  -s                    构建所有依赖并发布（无环境区分）"
   echo "  -o                    构建所有应用并发布（默认 feature-tag 环境）"
   echo "  -n '项目名1,项目名2'         构建指定的项目 hs-kh-server,hs-kh-admin 指定两个应用，注意使用最终要打包的文件夹名字即可 "
   echo "  -p '环境'             指定构建环境 (f=feature|stable、ft=feature-tag、u=uat|daily) 其中 f和t 环境是普通打包 ft是发布单打包"
   echo "  --c                   加上这个参数。使用当前分支部署，不支持 -p ft 参数共存。因为只支持普通打包 用于合并后分支打包"
   echo "  --m                   加上这个参数。使用master部署，不支持 -p ft 参数共存。因为只支持普通打包 用于你想回滚到master打包"
   echo "  --help                显示此帮助信息"
   echo ""
   echo "示例:"
   echo "  ob             默认构建所有项目，先构建所有依赖，然后构建所有应用部署(发布单)"
   echo "  ob -s          执行所有依赖构建发布，无环境"
   echo "  ob -o -n 'hs-kh-admin'     执行应用hs-kh-admin构建发布，默认 feature-tag 环境 "
   echo "  ob -o -n hs-kh-admin -p u --c    执行应用hs-kh-admin构建发布，默认 feature-tag 环境 使用当前该项目的分支 "
   echo "  ob -o -p u     执行所有应用构建发布，uat 环境 这是普通发布模式 "
}

get_current_branch(){
  if [[ -d "$1/.git" ]]; then
      current_branch=$(git -C "$1" rev-parse --abbrev-ref HEAD)
      echo "$current_branch"
  else
      log "错误：$1 不是一个 Git 仓库"
      exit 1
  fi
}

# 获取应用app
get_build_apps(){
    project_number="$1"  # 默认构建所有项目
    environment="$2"  # 默认环境为 "f"
    # 发布应用中的所有项目
    apps=$(read_config "apps")
    # 将字符串分割成数组
    while IFS=',' read -ra temp; do
      appList=("${temp[@]}")
    done < <(echo "$apps")
    # 需要构建的项目
    declare -a build_apps
    # 判断是否构建所有应用
    if [[ "$project_number" == "all" ]]; then
        build_apps=("${appList[@]}")
        echo "${build_apps[@]}"
        return 0
    fi
    # 判断是否单个项目
    if [[ ! "$project_number" == *","* ]]; then
        if [[ "$project_number" =~ ^[0-9]+$ ]]; then
            [[ $project_number -lt 0 || $project_number -ge ${#appList[@]} ]] && log "应用构建错误：参数 $project_number 超出范围。有效范围为 0 到 $((${#appList[@]} - 1))" && exit 1
            build_apps+=("${appList[$project_number]}")
        else
            # 存在就转换
            opsName=$(read_config "project.$project_number.opsName")
            if [[ -z "$opsName" ]]; then
              log "错误：$app 对应发布单不存在。流程终止。"
              exit 1
            fi
            build_apps+=("$opsName")
        fi
        echo "${build_apps[@]}"
        return 0
    fi

    # 多个项目，逗号分隔
    while IFS=',' read -ra temp; do
      elements=("${temp[@]}")
    done < <(echo "$project_number")
    for element in "${elements[@]}"; do
        if [[ "$element" =~ ^[0-9]+$ ]]; then
            # 索引检查
            [[ $element -lt 0 || $element -ge ${#appList[@]} ]] && log "应用构建错误：参数 $element 超出范围。有效范围为 0 到 $((${#appList[@]} - 1))" && exit 1
            build_apps+=("${appList[$element]}")
        else
          # 存在就转换
          opsName=$(read_config "project.$element.opsName")
          if [[ -z "$opsName" ]]; then
            log "错误：$app 对应发布单不存在。流程终止。"
            exit 1
          fi
          build_apps+=("$opsName")
        fi
    done

    echo "${build_apps[@]}"
    return 0
}

# 基础请求
base_request(){
  local url=$1
  local vops_token=$2
  # shellcheck disable=SC2129
  echo "$(date +'%Y-%m-%d %H:%M:%S') - 请求 URL: $url" >> "$log_file"
   api_response=$(curl -s "$url" \
        -H 'Accept: application/json, text/plain, */*' \
        -H 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6' \
        -H 'Connection: keep-alive' \
        -H "Cookie: vops_token=$vops_token" \
        -H 'Referer: https://vops.hszq8.com/app/flow/flow_detail' \
        -H 'Sec-Fetch-Dest: empty' \
        -H 'Sec-Fetch-Mode: cors' \
        -H 'Sec-Fetch-Site: same-origin' \
        -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0' \
        -H 'sec-ch-ua: "Chromium";v="124", "Microsoft Edge";v="124", "Not-A.Brand";v="99"' \
        -H 'sec-ch-ua-mobile: ?0' \
        -H 'sec-ch-ua-platform: "macOS"')
  echo "$(date +'%Y-%m-%d %H:%M:%S') - 响应: $api_response" >> "$log_file"
  echo "$api_response"
}
# 基础请求-post
# 基础请求-post
base_post_request(){
  local url=$1
  local vops_token=$2
  local data=$3



  # 记录请求的参数
  # shellcheck disable=SC2129
  echo "$(date +'%Y-%m-%d %H:%M:%S') - 请求 URL: $url" >> "$log_file"
  echo "$(date +'%Y-%m-%d %H:%M:%S') - 请求数据: $data" >> "$log_file"

  # 执行 POST 请求
  build_response=$(curl  --silent --location --request POST "$url" \
      --header 'Accept: application/json, text/plain, */*' \
      --header 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6' \
      --header 'Connection: keep-alive' \
      --header 'Origin: https://vops.hszq8.com' \
      --header 'Referer: https://vops.hszq8.com' \
      --header 'Sec-Fetch-Dest: empty' \
      --header 'Sec-Fetch-Mode: cors' \
      --header 'Sec-Fetch-Site: same-origin' \
      --header 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0' \
      --header 'sec-ch-ua: "Chromium";v="130", "Microsoft Edge";v="130", "Not?A_Brand";v="99"' \
      --header 'sec-ch-ua-mobile:?0' \
      --header 'sec-ch-ua-platform: "macOS"' \
      --header "Cookie: sidebarStatus=1; vops_token=$vops_token" \
      --header 'Content-Type: application/json;charset=UTF-8' \
      --header 'Host: vops.hszq8.com' \
      --data-raw "$data")

  # 记录响应结果
  echo "$(date +'%Y-%m-%d %H:%M:%S') - 响应: $build_response" >> "$log_file"

  # 返回响应结果
  echo "$build_response"
}


# 构建应用接口         build "$1 app" "$2 branch" "$3 key" "$4 value" "$5 token" $6 environment $7 skip_test
build(){
  ops_response=$(base_request "https://vops.hszq8.com/app/api/v1/app/$1" "$5")
  # gl(国际)  master(主站)
  zone=$(echo "$ops_response" | jq -r '.zone')
  # pt 平台 ft 金融工具
  business=$(echo "$ops_response" | jq -r '.business')
  # 打包指令操作
  build_cmd=$(echo "$ops_response" | jq -r '.build_cmd')
  build_env=""
  profile=""
  skip_test="$7"
   # 提取并遍历 server_nodes 的 keys
  while read -r key; do
    # vsgaws-ptft-beta 不支持
    # vsgaws-ptft-feature 不支持
    # mas-ptft-stable 马来-stable
    # mas-ptft-uat 马来-uat
    # hk-ptft-feature 主站feature
    # hk-ptft-uat 主站uat
    # hkaws-ptft-beta 主站beta 不支持
    # sgaws-ptft-beta 不支持
    if [[ "$key" == *"beta"* ]]; then
      continue
    fi
    if [[ "$key" == *"vsgaws"* ]]; then
      continue
    fi
    if [[ "$key" == *"sgaws"* ]]; then
      continue
    fi

    case "$6" in
      feature)
        if [[ "$zone" == "master" ]]; then
          if [[ "$key" == *"feature"* ]]; then
            build_env="$key"
            profile="feature"
            break
          fi
        elif [[ "$zone" == "gl" ]]; then
          if [[ "$key" == *"stable"* ]]; then
            build_env="$key"
            profile="stable"
            break
          fi
        else
          log "暂时不支持 $zone 区域 部署"
          continue
        fi
        ;;
      uat)
        if [[ "$key" == *"uat"* ]]; then
          build_env="$key"
          profile="uat"
          break
        fi
        ;;
    esac
  done < <(echo "$ops_response" | jq -r '.server_nodes | keys[]')
  # 检查 build_env 和 profile 是否定义
  if [ -z "$build_env" ]; then
    log "不支持的环境"
    return 0
  fi
  if [ -z "$profile" ]; then
    log "不支持的环境 profile"
    return 0
  fi
#  echo "build_cmd:$build_cmd"
#  echo "build_env:$build_env"
  last_build_cmd=$(echo "$build_cmd" | jq -r --arg key "$build_env" '.[$key][-1]')
#  echo "profile:$profile"
#  echo "last_build_cmd:$last_build_cmd"

  last_build_cmd=$(echo "$last_build_cmd" | sed -E "s/-P[[:space:]]*[a-zA-Z0-9_]+/-P$profile/g")
#  echo "last_build_cmd2:$last_build_cmd"
  # 判断 last_build_cmd 是否为空或为 "null"
  if [[ -z "$last_build_cmd" || "$last_build_cmd" == "null" || "$last_build_cmd" == *"null"* ]]; then
      log "应用：$1 环境：$build_env | $profile 构建指令:有误"
      return 0
  fi
  if [[ "$skip_test" -eq 1 ]]; then
    log "打包覆盖率"
     # 检查是否包含 -Dmaven.test.skip=false，如果没有，则添加
    if [[ ! "$last_build_cmd" =~ -Dmaven.test.skip=false ]]; then
        last_build_cmd="$last_build_cmd -Dmaven.test.skip=false"
        log "构建命令中未包含 '-Dmaven.test.skip=false'，已自动添加"
    fi
    # 检查是否包含 -Dmaven.test.skip=false，如果没有，则添加
    if [[ ! "$last_build_cmd" =~ -DskipTests=false ]]; then
        last_build_cmd="$last_build_cmd -DskipTests=false"
        log "构建命令中未包含 '-DskipTests=false'，已自动添加"
    fi
  else
    log "去掉打包覆盖率，提升打包速度"
    last_build_cmd=$(echo "$last_build_cmd" | sed -E "s/(-DskipTests=false| -Dmaven.test.skip=false)//g")
  fi
  log "最终打包指令：$last_build_cmd"
  ops_response=$(base_request "https://vops.hszq8.com/app/api/v1/resource/k8s_resource/$1/$build_env" "$5")
  # 检查 ops_response 是否包含错误信息 "无该应用权限"
  error_message=$(echo "$ops_response" | jq -r '.detail')
  if [[ "$error_message" == "无该应用权限" ]]; then
      # 记录错误并跳过当前任务
      log "错误：应用 $1 在环境 $build_env 中没有权限。跳过当前任务。"
      # 继续处理下一个任务
      return 0
  fi
  data=$(echo "$ops_response" | jq '.data')
  # 如果 data 为空，记录并跳过
  if [[ "$data" == "null" || -z "$data" ]]; then
      log "无效的响应数据：$ops_response，跳过当前任务。"
      return 0
  fi
  k8s_env_name=$(echo "$data" | jq -r '.k8s_env_name')
  config_jvm_raw=$(echo "$data" | awk -F'"config_jvm":' '{if (NF > 1) print $2}' | sed -E 's/^ *"([^"]+)".*$/\1/')
  env_config_checkList=$(echo "$data" | jq -r '.env_config_checkList | join(" ")')
  copies_cluster1=$(echo "$data" | jq -r '.copies_cluster1')
  copies_cluster2=$(echo "$data" | jq -r '.copies_cluster2')
  cpu_limits=$(echo "$data" | jq -r '.cpu_limits')
  mem_limits=$(echo "$data" | jq -r '.mem_limits')
  # 生成 JSON
  # 需要取个环境
  build_param_json=$(jq -n --arg name "$1" \
                 --arg topic "自动打包-$4" \
                 --arg branch "$2" \
                 --arg env_config_checkList "$env_config_checkList" \
                 --arg rev "$3" \
                 '{
                   "name": $name,
                   "topic": $topic,
                   "branch": $branch,
                   "rev": $rev,
                   "nodes": [
                     {
                       "env": "'"$build_env"'",
                       "deploy": "deploy",
                       "nodes": ["k8s"],
                       "sonarqube": "default",
                       "cmd": "'"$last_build_cmd"'",
                       "smart_doc": false,
                       "exclude_str": ".*"
                     }
                   ],
                   "is_prod": false,
                   "is_ci": false,
                   "switch_hstapm": false,
                   "config_jvm": "'"$config_jvm_raw"'",
                   "copies_cluster1": '"$copies_cluster1"',
                   "copies_cluster2": '"$copies_cluster2"',
                   "env_config_checkList": ($env_config_checkList | split(" ")),
                   "cpu_limits": "'"$cpu_limits"'",
                   "mem_limits": "'"$mem_limits"'",
                   "k8s_env_name": "'"$k8s_env_name"'"
                 }')
   # 执行请求
   build_response=$(curl  --silent --location --request POST "https://vops.hszq8.com/app/api/v1/app/$1/build" \
       --header 'Accept: application/json, text/plain, */*' \
       --header 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6' \
       --header 'Connection: keep-alive' \
       --header 'Origin: https://vops.hszq8.com' \
       --header 'Referer: https://vops.hszq8.com' \
       --header 'Sec-Fetch-Dest: empty' \
       --header 'Sec-Fetch-Mode: cors' \
       --header 'Sec-Fetch-Site: same-origin' \
       --header 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0' \
       --header 'sec-ch-ua: "Chromium";v="130", "Microsoft Edge";v="130", "Not?A_Brand";v="99"' \
       --header 'sec-ch-ua-mobile:?0' \
       --header 'sec-ch-ua-platform: "macOS"' \
       --header "Cookie: sidebarStatus=1; vops_token=$5" \
       --header 'Content-Type: application/json;charset=UTF-8' \
       --header 'Host: vops.hszq8.com' \
       --data-raw "$build_param_json")
  log "项目：$1 普通构建结果：$build_response"
}

printf_app_log() {
  # 应用列表
  local apps=("${!1}")
  # 构建状态
  local build_statuses=("${!2}")
  # 部署状态
  local run_statuses=("${!3}")
  local errors=("${!5}")

  local spin_char=$4
  # 构建时间
  local build_times=("${!6}")
  # 运行完成时间
  local run_times=("${!7}")
  local environment=$8

  # 输出表格标题
  echo "----------------------------$(date +'%Y-%m-%d %H:%M:%S')----------------------------"
  printf " %s :进行中     ⌛ :等待开始     ❌  :失败     ✅  :成功     ⚠️:已取消\n\n" "$spin_char"
  # 循环输出应用名和状态，实现对齐显示
  for ((i = 0; i < ${#apps[@]}; i++)); do
      local app_name="${apps[$i]}"
      local build_status="${build_statuses[$i]}"
      [[ -z "$build_status" ]] && build_status="⌛"
      [[ "$build_status" == "🔧" ]] && build_status="$spin_char"

      local run_status="${run_statuses[$i]}"
      [[ -z "$run_status" ]] && run_status="⌛"
      [[ "$run_status" == "🔧" ]] && run_status="$spin_char"

      local error="${errors[$i]}"
      [[ -z "$error" ]] && error=" "

      local build_time="${build_times[$i]}"
      if [[ -z "$build_time" ]]; then
        build_time=""
      else
        build_time="($build_time)"
      fi
      local run_time="${run_times[$i]}"
      if [[ -z "$run_time" ]]; then
        run_time=""
      else
        run_time="($run_time)"
      fi
      printf "%-30s 构建 %-5s%-12s 部署 %-5s%-12s    %s \n" \
          "$app_name" "$build_status" "$build_time"  "$run_status" "$run_time"  "$error"
  done
  echo ""
  echo "--------------------------------$environment-------------------------------------"
}
# 构建后置操作
build_post_options() {
  build_apps=("${!1}")
  build_app_ids=("${!2}")
  environment="$3"
  token="$4"

}
# 构建中操作
build_ing_options() {
  build_apps=("${!1}")
  build_app_ids=("${!2}")
  environment="$3"
  token="$4"

}

# 获取日志信息
get_app_log() {
  build_apps=("${!1}")
  build_app_ids=("${!2}")
  environment="$3"
  token="$4"
  # 构建状态
  declare -a build_statuses
  # 启动状态
  declare -a run_statuses
  # 异常
  declare -a errors
  declare -a build_times
  declare -a run_times

  local iteration=0
  local spinner_index=0
  # shellcheck disable=SC2034
  declare -A config_cache_num
  while :; do
    # 获取当前的旋转字符
    local spin_char="${spinner:spinner_index:1}"
    case "$environment" in
              feature-tag)
      for ((i = 0; i < ${#build_apps[@]}; i++)); do
        # 覆盖旧值
        errors[$i]=""
        run_times[$i]=""
        build_times[$i]=""
        local app_name="${build_apps[$i]}"
        local app_id="${build_app_ids[$i]}"
        build_response=$(base_request "https://vops.hszq8.com/app/api/v1/flow/build_history/$app_id" "$token")
        # 检查 status 是否为 success
        status=$(echo "$build_response" | jq -r '.status')
        if [[ "$status" != "success" ]]; then
            log "请求失败，status: $status"
            run_statuses[$i]="❌"
            build_statuses[$i]="❌"
            errors[$i]="失败原因：请求失败 $status"
            continue
        fi
        # 检查 data 是否存在且为非空数组
        data_count=$(echo "$build_response" | jq '.data | length')
        if [[ "$data_count" -eq 0 ]]; then
            log "data 为空或不存在: $build_response"
            run_statuses[$i]="❌"
            build_statuses[$i]="❌"
            errors[$i]="失败原因：请求失败 数据为空"
            continue
        fi
        last_build_data=$(echo "$build_response" | jq '.data[0]')
        last_build_user_name=$(echo "$last_build_data" | jq -r '.create_user')
        if [[ "${last_build_user_name}" != "${ops_user}" ]]; then
            log "data 为空或不存在: $build_response"
            run_statuses[$i]="❌"
            build_statuses[$i]="❌"
            errors[$i]="失败原因：未找到构建记录or被他人覆盖($last_build_user_name)"
            continue
        fi
        status=$(echo "$last_build_data" | jq -r '.status')
        # 已经成功了
        # 已经取消了
        if [[ "${status}" == "canceled" ]]; then
           run_statuses[$i]="⚠️"
           build_statuses[$i]="⚠️"
           errors[$i]="警告原因：任务已被取消"
           continue
        fi
        # 提取每个对象
        build_task=$(echo "$last_build_data" | jq '.subtask[0]')
        run_task=$(echo "$last_build_data" | jq '.subtask[2]')
        build_status=$(echo "$build_task" | jq -r '.status')
        build_m_time=$(echo "$build_task" | jq -r '.mtime' | awk -F'T' '{print $2}')
        run_m_time=$(echo "$run_task" | jq -r '.mtime' | awk -F'T' '{print $2}')
        run_status=$(echo "$run_task" | jq -r '.status')
        case "$run_status" in
            success)
              # 运行状态都是成功的。那整个项目都成功
              run_statuses[$i]="✅"
              run_times[$i]=$run_m_time
              ;;
            error)
              run_statuses[$i]="❌"
              run_times[$i]=$run_m_time
              errors[$i]="失败原因：启动失败"
              ;;
            canceled)
              run_statuses[$i]="⚠️"
              run_times[$i]=$run_m_time
              errors[$i]="警告原因：运行任务已被取消"
              ;;
            running)
              run_statuses[$i]="🔧"
              run_times[$i]=""
              ;;
            wait)
              run_statuses[$i]="⌛"
              run_times[$i]=""
              ;;
            *)
              echo "未知状态: $run_status"
              exit 1
              ;;
        esac
        case "$build_status" in
            success)
              build_statuses[$i]="✅"
              build_times[$i]=$build_m_time
              ;;
            error)
              build_statuses[$i]="❌"
              build_times[$i]=$build_m_time
              errors[$i]="失败原因：构建失败"
              ;;
            canceled)
              build_statuses[$i]="⚠️"
              build_times[$i]=$build_m_time
              errors[$i]="警告原因：构建任务已被取消"
              break
              ;;
            running)
              build_statuses[$i]="🔧"
              build_times[$i]=""
              ;;
            wait)
              build_statuses[$i]="⌛"
              build_times[$i]=""
              ;;
            *)
              echo "未知状态: $build_status"
              exit 1
              ;;
        esac
      done
      ;;
    feature|uat|stable)
      # 缓存。builds 接口太慢。缓存一次num查详情比较好
      for ((i = 0; i < ${#build_apps[@]}; i++)); do
        local app_name="${build_apps[$i]}"
        local num=""
        local last_build_data=""
        # 覆盖旧值
        errors[$i]=""
        run_times[$i]=""
        build_times[$i]=""
        if [[ -n "${config_cache_num[$app_name]}" ]]; then
          num="${config_cache_num[$app_name]}"
          build_response=$(base_request "https://vops.hszq8.com/app/api/v1/app/$app_name/build/$num/info" "$token")
          # 检查 status 是否为 success
          status=$(echo "$build_response" | jq -r '.status')
          if [[ "$status" != "success" ]]; then
              log "请求失败，status: $status"
              run_statuses[$i]="❌"
              build_statuses[$i]="❌"
              errors[$i]="失败原因：请求失败 $status"
              continue
          fi
          last_build_data=$(echo "$build_response" | jq '.data')
        else
          build_response=$(base_request "https://vops.hszq8.com/app/api/v1/app/$app_name/get_list/builds" "$token")
          # 判断返回的 body 是否为空
          if [[ -z "$build_response" || "$build_response" == "[]" ]]; then
              log "data 为空或不存在: $build_response"
              run_statuses[$i]="❌"
              build_statuses[$i]="❌"
              errors[$i]="失败原因：请求失败 数据为空"
              continue
          fi
          # 检查 data 是否存在且为非空数组
          # 获取第一个元素
          last_build_data=$(echo "$build_response" | jq -r '.[0]')
          if [[ "$last_build_data" == "null" || -z "$last_build_data" ]]; then
              log "未找到有效的构建数据: $build_response"
              run_statuses[$i]="❌"
              build_statuses[$i]="❌"
              errors[$i]="失败原因：未找到有效构建数据"
              continue
          fi
          last_build_user_name=$(echo "$last_build_data" | jq -r '.user.user')
          if [[ "${last_build_user_name}" != "${ops_user}" ]]; then
              log "data 为空或不存在: $build_response"
              run_statuses[$i]="❌"
              build_statuses[$i]="❌"
              errors[$i]="失败原因：未找到构建记录or被他人覆盖($last_build_user_name)"
              continue
          fi
          num=$(echo "$last_build_data" | jq -r '.num')
          config_cache_num["$app_name"]="$num"
        fi
        status=$(echo "$last_build_data" | jq -r  '.state.status')
        # 提取每个对象
        build_task=$(echo "$last_build_data" | jq '.jobs[0]')
        run_task=$(echo "$last_build_data" | jq '.jobs[2]')
        build_status=$(echo "$build_task" | jq -r '.state.status')
        build_m_time=$(echo "$build_task" | jq -r '.state.last_time' | awk '{split($2, a, "."); print a[1]}')
        run_m_time=$(echo "$run_task" | jq -r '.state.last_time' | awk '{split($2, a, "."); print a[1]}')
        run_status=$(echo "$run_task" | jq -r '.state.status')
        build_url="https://vops.hszq8.com/app/app/$app_name/his_build/$num/log?worker=cidv2"
        case "$run_status" in
            success)
              # 运行状态都是成功的。那整个项目都成功
              run_statuses[$i]="✅"
              run_times[$i]=$run_m_time
              ;;
            error)
              run_statuses[$i]="❌"
              run_times[$i]=$run_m_time
              errors[$i]="失败原因：启动失败($build_url)"
              ;;
            canceled)
              run_statuses[$i]="⚠️"
              run_times[$i]=$run_m_time
              errors[$i]="警告原因：运行任务已被取消($build_url)"
              ;;
            running)
              run_statuses[$i]="🔧"
              run_times[$i]=""
              ;;
            create)
              run_statuses[$i]="⌛"
              run_times[$i]=""
              ;;
            *)
              echo "未知状态: $run_status"
              exit 1
              ;;
        esac
        case "$build_status" in
            success)
              build_statuses[$i]="✅"
              build_times[$i]=$build_m_time
              ;;
            error)
              build_statuses[$i]="❌"
              build_times[$i]=$build_m_time
              errors[$i]="失败原因：构建失败($build_url)"
              ;;
            canceled)
              build_statuses[$i]="⚠️"
              build_times[$i]=$build_m_time
              errors[$i]="警告原因：构建任务已被取消($build_url)"
              break
              ;;
            running)
              build_statuses[$i]="🔧"
              build_times[$i]=""
              ;;
            create)
              build_statuses[$i]="⌛"
              build_times[$i]=""
              ;;
            *)
              echo "未知状态: $build_status"
              exit 1
              ;;
        esac
      done
      ;;
    esac
    clear
    # 调用打印函数
    printf_app_log build_apps[@] build_statuses[@]  run_statuses[@] "$spin_char" errors[@] build_times[@] run_times[@] "$environment"
    # 检查是否所有任务完成
    all_done=true
    for status in "${build_statuses[@]}" "${run_statuses[@]}"; do
      if [[ "$status" == "🔧" ]]; then
        all_done=false
        break
      fi
    done
    # 如果所有状态都成功，则退出
    if $all_done; then
      echo "所有任务已完成！"
      break
    fi
    # 构建中的操作
    build_ing_options build_apps[@] build_app_ids[@] "$environment" "$token"
    # 旋转字符更新
    spinner_index=$(( (spinner_index + 1) % 4 ))
    # 等待2秒
    sleep 1
    # 模拟迭代次数
    iteration=$((iteration + 1))
  done
}

# 构建应用
build_app(){
    project_number="$1"  # 默认构建所有项目
    environment="$2"
    current_branch="$4"  # 默认是0 不用
    skip_test="$5"  # 默认是0 不用
    # shellcheck disable=SC2178
    # shellcheck disable=SC2207
    build_apps=($(get_build_apps "$project_number" "$environment"))
    # 需要构建的项目id
    declare -a build_app_ids
    # shellcheck disable=SC2145
    log "需构建应用: ${build_apps[@]} 构建环境 $environment"
    for app in "${build_apps[@]}"; do
      app_path=$(read_config "project.$app.path")
      if [ -z "$app_path" ]; then
        log "$app 对应路径不存在，流程终止。"
        exit 1
      fi
      case "$environment" in
          feature-tag)
           # 获取项目id
            # project.hs-stock-hq-reminder.flow_app_id=4127
            flow_app_id=$(read_config "project.$app_path.flow_app_id")
            api_response=$(base_post_request "https://vops.hszq8.com/app/api/v1/flow/build_and_deploy/$flow_app_id" "$3" "")
            log "项目($flow_app_id)：$app 发布单构建结果：$api_response"
            build_app_ids+=("$flow_app_id")
            ;;
          feature|uat|stable)
            # 只有普通构建才需要获取当前分支
            if [[ $current_branch -eq 1 ]]; then
                branch=$(get_current_branch "$base_path/$app_path")
            elif [[ $current_branch -eq 2 ]]; then
                branch="master"
            else
                branch=$(read_config "project.$app_path.source.branch")
                if [ -z "$branch" ]; then
                  echo "$app 对应分支 $branch 不存在，流程终止。"
                  exit 1
                fi
            fi
             # 查询分支最新提交
            api_response=$(base_request "https://vops.hszq8.com/app/api/v1/app/$app/revs?branch=$branch" "$3")
            key=$(echo "$api_response" | jq -r '.[0] | keys[0]')
            value=$(echo "$api_response" | jq -r ".[0][\"$key\"]")
            if [ -z "$key" ] || [ -z "$value" ]; then
                log "$app 读取分支 $branch 提交 Error: Could not extract key or value from JSON."
                exit 1
            fi
            log "最后一次提交：$app 构建分支 $branch 提交rev $key 提交说明 $value"
            build "$app" "$branch" "$key" "$value" "$3" "$environment" "$skip_test"
            ;;
      esac
    done
    log "构建成功。2s后进入构建结果打印"
    sleep 2
    # 打印日志
    get_app_log build_apps[@] build_app_ids[@] "$environment" "$3"
    # 后置处理
    build_post_options build_apps[@] build_app_ids[@] "$environment" "$3"
    exit 1
}

# 获取token
# 获取token
get_vops_token() {
  # 1. 调用接口获取git地址数组
  vops_result=$(curl -s "https://admin-feature.vbkrhk.com/auto-ai/vops/user/detail?userName=$1")
  log " 获取 $1 的登录态"
  local code
  local msg
  local data
  local ops_token
  local depart
  local name
  code=$(echo "$vops_result" | jq -r '.code')
  msg=$(echo "$vops_result" | jq -r '.msg')
  data=$(echo "$vops_result" | jq -r '.data')
   # 判断是否异常
  if [[ "$code" != "0" ]]; then
    log "登录异常，错误信息: $msg"
    return 1
  fi
  # 检查 data 是否为空
  if [[ "$data" == "null" || -z "$data" ]]; then
    log "返回数据为空，请检查用户插件是否正确。"
    return 1
  fi
  # 提取必要的字段
  ops_token=$(echo "$data" | jq -r '.opsToken')
  depart=$(echo "$data" | jq -r '.depart')
  name=$(echo "$data" | jq -r '.name')
   # 校验data是否有值
  if [ -z "$ops_token" ]; then
    log "请域内刷新一下ops"
    exit 1
  fi
  # 打印结果
  log "欢迎 $depart 的$name "
  echo "$ops_token"
}

build_support_app(){
  project_number="$1"  # 默认构建所有项目
  environment="$2"
  token="$3"
  log "暂时不支持构建依赖发布单"
  exit 1
}
# 转换字符
convert_environment() {
  local env="$1"  # 获取传入的字符

  case "$env" in
    "")
      echo "feature-tag"  # 没传时默认是 feature-tag
      ;;
    s)
      echo "feature"
      ;;
    ft)
      echo "feature-tag"
      ;;
    f)
      echo "feature"
      ;;
    u)
      echo "uat"
      ;;
    d)
      echo "uat"
      ;;
    *)
      echo "不支持的环境类型：$env"  # 提示不支持的字符
      exit 1
      ;;
  esac
}

# 主流程
# shellcheck disable=SC1073
main() {
  set -e
  if [ ! -f "$clone_config_file" ]; then
      echo "错误：ops文件不存在。终止运行。"
      exit 1
  fi
  # 设置默认值
  build_type="all"  # 默认构建类型为 "全部构建"
  project_number="all"  # 默认构建所有项目
  environment_param="ft"  # 默认环境为 "ft"
  current_branch=0  # 默认环境为 "ft"
  skip_test=0  # 覆盖率打包

  # 解析命令行参数
  while [[ "$1" != "" ]]; do
    case $1 in
      -s)
        build_type="support"  # 构建依赖
        ;;
      -o)
        build_type="app"  # 构建应用
        ;;
      -n)
        shift
        project_number="$1"  # 指定构建的项目序号
        ;;
      -p)
        shift
        environment_param="$1"  # 指定构建环境
        ;;
      --c)
         # 使用当前分支部署
          current_branch=1
          ;;
      --m)
         # 使用当前分支部署
          current_branch=2
          ;;
      --t)
         # 覆盖率打包
          skip_test=1
          ;;
      --help)
        show_help  # 调用帮助函数
        exit 0  # 添加这行，在显示帮助后退出程序
        ;;
      *)
        echo "无效的选项: $1"
        show_help
        exit 0  # 添加这行，在显示帮助后退出程序
        ;;
    esac
    shift
  done
  environment=$(convert_environment "$environment_param")

  # 打印解析后的结果
  log "构建类型：$build_type"
  log "项目序号：$project_number"
  log "构建环境：$environment"
  if [[ "$current_branch" -eq 1 ]]; then
    log "构建当前分支"
  fi
  if [[ "$current_branch" -eq 2 ]]; then
    log "构建master分支"
  fi
  if [[ "$skip_test" -eq 1 ]]; then
    log "打包覆盖率"
  fi
  # 1. 获取能用的token
  token=$(get_vops_token "$ops_user")
  # 打印获取到的token
  log "获取 ops token: $token"

  if [[ "$build_type" == "all" ]]; then
    log "执行所有应用,先构建依赖，项目编号：$project_number ,环境：$environment"
    build_support_app "$project_number" "$environment" "$token"
    # shellcheck disable=SC2317
    build_app "$project_number" "$environment" "$token" "$current_branch" "$skip_test"
    # shellcheck disable=SC2317
    exit 0
  fi
  if [[ "$build_type" == "app" ]]; then
    log "执行构建应用，项目编号：$project_number ,环境：$environment"
    build_app "$project_number" "$environment" "$token" "$current_branch" "$skip_test"
    # shellcheck disable=SC2317
    exit 0
  fi
  if [[ "$build_type" == "support" ]]; then
    log "执行构建依赖应用，项目编号：$project_number ,环境：$environment"
    build_support_app "$project_number" "$environment"
    # shellcheck disable=SC2317
    exit 0
  fi
}

# 执行主流程
main "$@"